package r25.engine;

import java.util.List;

import r25.board.ControlMove;
import r25.board.IBoard;
import r25.board.RoomPosition;
import r25.character.ICharacter;
import r25.character.IInRoomObject;
import r25.engine.IGameService.GAME_MODE;
import r25.room.IRoom;

public interface IGameInstance {
	public enum GAME_WINNER {
		PRISONERS, GAME
	}

	public enum CHARACTER_ACTION {
		LOOK, MOVE, PUSH, CONTROL
	}

	public enum CHARACTER_TOKEN_ACTION {
		SET_REMINDER_TOKEN
	}

	public enum CHARACTER_ACTION_STATUS {
		ACTION, EXTRA_ACTION, END
	}

	public abstract List<CHARACTER_ACTION> availableCharacterActions();

	public abstract CHARACTER_ACTION_STATUS getCurrentCharacterStatus();

	public abstract CharacterActionResponse executeCharacterExtraAction(
			CHARACTER_ACTION action, RoomPosition targetRoomPosition,
			ICharacter targetCharacter, ControlMove controlMove);

	public abstract CharacterActionResponse passCharacterAction();

	public abstract CharacterActionResponse executeCharacterAction(
			CHARACTER_ACTION action, RoomPosition targetRoomPosition,
			ICharacter character, ControlMove controlMove);

	public abstract boolean endCharacterActionPhase();

	public abstract void programCharacterAction(int characterIndex,
			CHARACTER_ACTION action) throws Exception;

	public abstract String getId();

	public abstract void start() throws Exception;

	public abstract List<ICharacter> getWinners();

	public abstract List<String> getPlayers();

	public abstract List<ICharacter> getCharactersTurnOrder();

	public abstract boolean isStarted();

	public abstract boolean isGameOver();

	public abstract int getCharacterActionIndex();

	public abstract int getCharacterIndex();

	public abstract ICharacter getCurrentCharacter();

	public abstract int getMaxPlayer();

	public abstract int getTurnIndex();

	public abstract int getMaxTurn();

	public abstract int getMaxCharacter();

	public abstract IBoard getBoard();

	public abstract GAME_MODE getMode();

	public abstract List<IInRoomObject> getInRoomObjects(IRoom room,
			boolean withReminderToken);

	public abstract void pushEvent(IEvent event);

	public abstract List<IEvent> getGameLogEvents();

	public abstract GameStateTimeStamp getCurrentStateTimeStamp();

	public abstract int getCurrentCharacterMaxAction();

	public abstract List<ICharacter> getOtherCharactersInRoomObjects(
			IRoom room, ICharacter currentCharacter);

	public abstract CharacterActionResponse playReminderToken(
			RoomPosition targetRoomPosition);

	public abstract List<IEvent> getCheckEvents();

	public abstract void gameOver(GAME_WINNER winner);

	public abstract int getPrisonersCount();

}
